summaryrefslogtreecommitdiff
path: root/app/[lng]
diff options
context:
space:
mode:
Diffstat (limited to 'app/[lng]')
-rw-r--r--app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx92
1 files changed, 80 insertions, 12 deletions
diff --git a/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx b/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx
index dc6fbe7c..67fbfd9f 100644
--- a/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx
+++ b/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx
@@ -5,16 +5,20 @@ import { useDropzone } from "react-dropzone";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Skeleton } from "@/components/ui/skeleton";
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { InfoIcon, Upload } from "lucide-react";
import { SwpTable } from "@/lib/swp/table/swp-table";
+import { SwpInboxTable } from "@/lib/swp/table/swp-inbox-table";
import { SwpTableToolbar } from "@/lib/swp/table/swp-table-toolbar";
import {
fetchVendorDocuments,
fetchVendorProjects,
fetchVendorSwpStats,
getVendorSessionInfo,
+ fetchVendorUploadedFiles,
} from "@/lib/swp/vendor-actions";
import type { DocumentListItem } from "@/lib/swp/document-service";
+import type { SwpFileApiResponse } from "@/lib/swp/api-client";
import { toast } from "sonner";
interface VendorDocumentPageProps {
@@ -27,6 +31,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP
// 상태 관리
const [documents, setDocuments] = useState<DocumentListItem[]>([]);
+ const [inboxFiles, setInboxFiles] = useState<SwpFileApiResponse[]>([]);
const [projNo, setProjNo] = useState(initialProjNo);
const [projects, setProjects] = useState<Array<{ PROJ_NO: string; PROJ_NM: string }>>([]);
const [stats, setStats] = useState({
@@ -46,12 +51,16 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP
const [isRefreshing, setIsRefreshing] = useState(false);
const [error, setError] = useState<string | null>(null);
+ // 탭 상태
+ const [activeTab, setActiveTab] = useState("inbox");
+
// 클라이언트 필터
const [searchFilters, setSearchFilters] = useState({
docNo: (searchParams.docNo as string) || "",
docTitle: (searchParams.docTitle as string) || "",
pkgNo: (searchParams.pkgNo as string) || "",
stage: (searchParams.stage as string) || "",
+ status: (searchParams.status as string) || "",
});
// Dropzone 설정
@@ -86,12 +95,14 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP
// 초기 프로젝트가 있으면 문서 로드
if (initialProjNo) {
- const [documentsData, statsData] = await Promise.all([
+ const [documentsData, statsData, inboxFilesData] = await Promise.all([
fetchVendorDocuments(initialProjNo),
fetchVendorSwpStats(initialProjNo),
+ fetchVendorUploadedFiles(initialProjNo),
]);
setDocuments(documentsData);
setStats(statsData);
+ setInboxFiles(inboxFilesData);
}
} catch (err) {
console.error("초기 데이터 로드 실패:", err);
@@ -109,13 +120,15 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP
setIsRefreshing(true);
setError(null);
- const [documentsData, statsData] = await Promise.all([
+ const [documentsData, statsData, inboxFilesData] = await Promise.all([
fetchVendorDocuments(projNo),
fetchVendorSwpStats(projNo),
+ fetchVendorUploadedFiles(projNo),
]);
setDocuments(documentsData);
setStats(statsData);
+ setInboxFiles(inboxFilesData);
toast.success("문서 목록을 갱신했습니다");
} catch (err) {
console.error("문서 로드 실패:", err);
@@ -150,7 +163,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP
loadDocuments();
};
- // 클라이언트 사이드 필터링
+ // 클라이언트 사이드 필터링 - VDR Documents
const filteredDocuments = useMemo(() => {
return documents.filter((doc) => {
if (searchFilters.docNo && !doc.DOC_NO.toLowerCase().includes(searchFilters.docNo.toLowerCase())) {
@@ -165,10 +178,43 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP
if (searchFilters.stage && doc.STAGE !== searchFilters.stage) {
return false;
}
+ if (searchFilters.status) {
+ const statusLower = searchFilters.status.toLowerCase();
+ const docStatus = doc.LTST_ACTV_STAT?.toLowerCase() || "";
+ if (!docStatus.includes(statusLower)) {
+ return false;
+ }
+ }
return true;
});
}, [documents, searchFilters]);
+ // 클라이언트 사이드 필터링 - Inbox Files
+ const filteredInboxFiles = useMemo(() => {
+ return inboxFiles.filter((file) => {
+ if (searchFilters.docNo && !file.OWN_DOC_NO.toLowerCase().includes(searchFilters.docNo.toLowerCase())) {
+ return false;
+ }
+ if (searchFilters.docTitle && !file.FILE_NM.toLowerCase().includes(searchFilters.docTitle.toLowerCase())) {
+ return false;
+ }
+ if (searchFilters.pkgNo && !file.PKG_NO?.toLowerCase().includes(searchFilters.pkgNo.toLowerCase())) {
+ return false;
+ }
+ if (searchFilters.stage && file.STAGE !== searchFilters.stage) {
+ return false;
+ }
+ if (searchFilters.status) {
+ const statusLower = searchFilters.status.toLowerCase();
+ const fileStatus = file.STAT_NM?.toLowerCase() || file.STAT?.toLowerCase() || "";
+ if (!fileStatus.includes(statusLower)) {
+ return false;
+ }
+ }
+ return true;
+ });
+ }, [inboxFiles, searchFilters]);
+
if (isLoading) {
return (
<Card>
@@ -212,7 +258,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP
)}
{/* 통계 카드 */}
- <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
+ {/* <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<Card>
<CardHeader className="pb-3">
<CardDescription>할당된 문서</CardDescription>
@@ -239,7 +285,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP
</CardTitle>
</CardHeader>
</Card>
- </div>
+ </div> */}
{/* 안내 메시지 */}
{documents.length === 0 && !projNo && (
@@ -251,7 +297,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP
</Alert>
)}
- {/* 메인 테이블 */}
+ {/* 메인 테이블 - 탭 구조 */}
<Card>
<CardHeader>
<SwpTableToolbar
@@ -270,12 +316,34 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP
/>
</CardHeader>
<CardContent>
- <SwpTable
- documents={filteredDocuments}
- projNo={projNo}
- vendorCode={vendorInfo?.vendorCode || ""}
- userId={String(vendorInfo?.vendorId || "")}
- />
+ <Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
+ <TabsList className="grid w-full grid-cols-2">
+ <TabsTrigger value="inbox">
+ SBOX (ALL)
+ {/* ({filteredInboxFiles.length}) */}
+ </TabsTrigger>
+ <TabsTrigger value="documents">
+ VDR Documents (Received)
+ {/* ({filteredDocuments.length}) */}
+ </TabsTrigger>
+ </TabsList>
+ <TabsContent value="inbox" className="mt-4">
+ <SwpInboxTable
+ files={filteredInboxFiles}
+ projNo={projNo}
+ vendorCode={vendorInfo?.vendorCode || ""}
+ userId={String(vendorInfo?.vendorId || "")}
+ />
+ </TabsContent>
+ <TabsContent value="documents" className="mt-4">
+ <SwpTable
+ documents={filteredDocuments}
+ projNo={projNo}
+ vendorCode={vendorInfo?.vendorCode || ""}
+ userId={String(vendorInfo?.vendorId || "")}
+ />
+ </TabsContent>
+ </Tabs>
</CardContent>
</Card>
</div>